home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / sunprom / sun3.md / vm.c < prev    next >
C/C++ Source or Header  |  1990-09-17  |  6KB  |  215 lines

  1. /* vm.c -
  2.  *
  3.  *         This file contains all hardware dependent routines for Sun2's and
  4.  *    Sun3's.  I will not attempt to explain the Sun mapping hardware in 
  5.  *    here.  See the Sun2 and Sun3 architecture manuals for details on
  6.  *    the mapping hardware.
  7.  *
  8.  * Copyright (C) 1985 Regents of the University of California
  9.  * All rights reserved.
  10.  */
  11.  
  12. #ifdef notdef
  13. static char rcsid[] = "$Header: /sprite/src/boot/sunprom/sun3.md/RCS/vm.c,v 1.1 90/09/17 10:51:48 rab Exp Locker: rab $ SPRITE (Berkeley)";
  14. #endif not lint
  15.  
  16. #include "sprite.h"
  17. #include "vmSunConst.h"
  18. #include "vmMachInt.h"
  19. #include "vm.h"
  20. #include "mach.h"
  21.  
  22. /*
  23.  * Macros to translate from a virtual page to a physical page and back.
  24.  */
  25. #define    VirtToPhysPage(pfNum) ((pfNum) << VMMACH_CLUSTER_SHIFT)
  26. #define    PhysToVirtPage(pfNum) ((pfNum) >> VMMACH_CLUSTER_SHIFT)
  27.  
  28. /*
  29.  * Macro to get a pointer into a software segment's hardware segment table.
  30.  */
  31. #define GetHardSegPtr(machPtr, segNum) \
  32.     ((machPtr)->segTablePtr + (segNum) - (machPtr)->offset)
  33.  
  34.  
  35.  
  36. /*
  37.  ----------------------------------------------------------------------
  38.  *
  39.  * VmMach_MapInDevice --
  40.  *
  41.  *    Map a device at some physical address into kernel virtual address.
  42.  *    This is for use by the controller initialization routines.
  43.  *    This routine looks for a free page in the special range of
  44.  *    kernel virtual that is reserved for this kind of thing and
  45.  *    sets up the page table so that it references the device.
  46.  *
  47.  * Results:
  48.  *    The kernel virtual address needed to reference the device is returned.
  49.  *
  50.  * Side effects:
  51.  *    The hardware page table is modified.  This may steal another
  52.  *    page from kernel virtual space, unless a page can be cleverly re-used.
  53.  *
  54.  *----------------------------------------------------------------------
  55.  */
  56. Address
  57. VmMach_MapInDevice(devPhysAddr, type)
  58.     Address    devPhysAddr;    /* Physical address of the device to map in */
  59.     int        type;        /* Value for the page table entry type field.
  60.                  * This depends on the address space that
  61.                  * the devices live in, ie. VME D16 or D32 */
  62. {
  63.     Address         virtAddr;
  64.     Address        freeVirtAddr = (Address)0;
  65.     Address        freePMEGAddr = (Address)0;
  66.     int            page;
  67.     int            pageFrame;
  68.     VmMachPTE        pte;
  69.  
  70.     /*
  71.      * Get the page frame for the physical device so we can
  72.      * compare it against existing pte's.
  73.      */
  74.     pageFrame = (unsigned)devPhysAddr >> VMMACH_PAGE_SHIFT_INT;
  75.  
  76.     /*
  77.      * Spin through the segments and their pages looking for a free
  78.      * page or a virtual page that is already mapped to the physical page.
  79.      */
  80.     virtAddr = (Address)VMMACH_DEV_START_ADDR;
  81.  
  82.     pte = VMMACH_RESIDENT_BIT | VMMACH_KRW_PROT | pageFrame;
  83. #ifdef sun3
  84.     pte |= VMMACH_DONT_CACHE_BIT;
  85. #endif
  86.     VmMachSetPageType(pte, type);
  87.     VmMachSetPageMap(virtAddr, pte);
  88.     /*
  89.      * Return the kernel virtual address used to access it.
  90.      */
  91.     return(virtAddr + ((int)devPhysAddr & VMMACH_OFFSET_MASK_INT));
  92. }
  93.  
  94. #define DMAPAGES  (VMMACH_DMA_SIZE / VMMACH_PAGE_SIZE_INT)
  95. static    Boolean    dmaPageBitMap[DMAPAGES];
  96.  
  97.  
  98. /*
  99.  ----------------------------------------------------------------------
  100.  *
  101.  * VmMach_DMAAlloc --
  102.  *
  103.  *    Allocate a set of virtual pages to a routine for mapping purposes.
  104.  *    
  105.  * Results:
  106.  *    Pointer into kernel virtual address space of where to access the
  107.  *    memory, or NIL if the request couldn't be satisfied.
  108.  *
  109.  * Side effects:
  110.  *    The hardware page table is modified.
  111.  *
  112.  *----------------------------------------------------------------------
  113.  */
  114. Address
  115. VmMach_DMAAlloc(numBytes, srcAddr)
  116.     int        numBytes;        /* Number of bytes to map in. */
  117.     Address    srcAddr;    /* Kernel virtual address to start mapping in.*/
  118. {
  119.     Address    beginAddr;
  120.     Address    endAddr;
  121.     int        numPages;
  122.     int        i, j;
  123.     VmMachPTE    pte;
  124.     Boolean    foundIt = FALSE;
  125.     int        virtPage;
  126.     static initialized = FALSE;
  127.  
  128.      /* calculate number of pages needed */
  129.                         /* beginning of first page */
  130.     beginAddr = (Address) (((unsigned int)(srcAddr)) & ~VMMACH_OFFSET_MASK_INT);
  131.                         /* begging of last page */
  132.     endAddr = (Address) ((((unsigned int) srcAddr) + numBytes) &
  133.         ~VMMACH_OFFSET_MASK_INT);
  134.     numPages = (((unsigned int) endAddr) >> VMMACH_PAGE_SHIFT_INT) -
  135.         (((unsigned int) beginAddr) >> VMMACH_PAGE_SHIFT_INT) + 1;
  136.  
  137.     /* see if request can be satisfied */
  138.     for (i = 0; i < DMAPAGES; i++) {
  139.     if (dmaPageBitMap[i] == 1) {
  140.         continue;
  141.     }
  142.     for (j = 1; j < numPages; j++) {
  143.         if (dmaPageBitMap[i + j] == 1) {
  144.         break;
  145.         }
  146.     }
  147.     if (j == numPages) {
  148.         foundIt = TRUE;
  149.         break;
  150.     }
  151.     }
  152.     if (!foundIt) {
  153.     return (Address) NIL;
  154.     }
  155.     for (j = 0; j < numPages; j++) {
  156.     unsigned frame;
  157.     dmaPageBitMap[i + j] = 1;    /* allocate page */
  158.     virtPage = ((unsigned int) srcAddr) >> VMMACH_PAGE_SHIFT_INT;
  159.     pte = VmMachGetPageMap(srcAddr);
  160.     VmMachSetPageMap((Address) (((i + j) * VMMACH_PAGE_SIZE_INT) +
  161.         VMMACH_DMA_START_ADDR), pte);
  162.     srcAddr += VMMACH_PAGE_SIZE_INT;
  163.     }
  164.     beginAddr = (Address) (VMMACH_DMA_START_ADDR + (i * VMMACH_PAGE_SIZE_INT) +
  165.         (((unsigned int) srcAddr) & VMMACH_OFFSET_MASK_INT));
  166.     return beginAddr;
  167. }
  168.  
  169.  
  170. /*
  171.  ----------------------------------------------------------------------
  172.  *
  173.  * VmMach_DMAFree --
  174.  *
  175.  *    Free a previously allocated set of virtual pages for a routine that
  176.  *    used them for mapping purposes.
  177.  *    
  178.  * Results:
  179.  *    None.
  180.  *
  181.  * Side effects:
  182.  *    The hardware page table is modified.
  183.  *
  184.  *----------------------------------------------------------------------
  185.  */
  186. void
  187. VmMach_DMAFree(numBytes, mapAddr)
  188.     int        numBytes;        /* Number of bytes to map in. */
  189.     Address    mapAddr;    /* Kernel virtual address to unmap.*/
  190. {
  191.     Address    beginAddr;
  192.     Address    endAddr;
  193.     int        numPages;
  194.     int        i, j;
  195.     Boolean    foundIt = FALSE;
  196.     int        virtPage;
  197.  
  198.     /* calculate number of pages to free */
  199.                         /* beginning of first page */
  200.     beginAddr = (Address) (((unsigned int) mapAddr) & ~VMMACH_OFFSET_MASK_INT);
  201.                         /* beginning of last page */
  202.     endAddr = (Address) ((((unsigned int) mapAddr) + numBytes) &
  203.         ~VMMACH_OFFSET_MASK_INT);
  204.     numPages = (((unsigned int) endAddr) >> VMMACH_PAGE_SHIFT_INT) -
  205.         (((unsigned int) beginAddr) >> VMMACH_PAGE_SHIFT_INT) + 1;
  206.  
  207.     i = (((unsigned int) mapAddr) >> VMMACH_PAGE_SHIFT_INT) -
  208.     (VMMACH_DMA_START_ADDR >> VMMACH_PAGE_SHIFT_INT);
  209.     for (j = 0; j < numPages; j++) {
  210.     dmaPageBitMap[i + j] = 0;    /* free page */
  211.     }
  212.     return;
  213. }
  214.  
  215.